package com.jtny.nytb.config.measurementtype.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jtny.component.contants.GenericConstants;
import com.jtny.component.core.util.PageUtils;
import com.jtny.component.core.util.QueryWrapperUtils;
import com.jtny.component.dto.CurrentUserDTO;
import com.jtny.component.entity.LocalHolder;
import com.jtny.component.entity.PageData;
import com.jtny.component.enums.GenericStatusEnum;
import com.jtny.component.exception.ServiceException;
import com.jtny.component.util.BeanUtils;
import com.jtny.component.util.CurrentUserUtils;
import com.jtny.nytb.config.errorcode.MeasurementTypeErrorCodeEnum;
import com.jtny.nytb.config.measurementtype.dao.MeasurementTypeDAO;
import com.jtny.nytb.config.measurementtype.domain.MeasurementTypeDO;
import com.jtny.nytb.config.measurementtype.dto.MeasurementTypeDTO;
import com.jtny.nytb.config.measurementtype.dto.MeasurementTypePageQueryDTO;
import com.jtny.nytb.config.measurementtype.dto.RepeatMeasurementTypeDTO;
import com.jtny.nytb.config.measurementtype.service.MeasurementTypeService;
import com.jtny.nytb.config.measurementtype.vo.MeasurementTypePageQueryParamVO;
import com.jtny.nytb.config.measurementtype.vo.MeasurementTypeVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 计量单位分类Service实现类，具体实现MeasurementTypeService定义的接口
 *
 * @author 智慧能源中心 - lyq
 * @package com.jtny.nytb.config.measurementType.service.impl
 * @fileName MeasurementTypeServiceImpl.java
 * @createTime 2023年9月01日 10:03
 * @Copyright© 2023 jtny
 * 江投能源技术研究院 版权所有
 */
@Service
@Slf4j
@AllArgsConstructor
public class MeasurementTypeServiceImpl implements MeasurementTypeService {
    @Resource
    private MeasurementTypeDAO measurementTypeDAO;

    @Override
    public MeasurementTypeDTO save(MeasurementTypeDTO measurementTypeDTO) throws ServiceException {

        // 将DTO对象的属性复制给DO对象
        MeasurementTypeDO measurementTypeDO = BeanUtils.copyToObject(measurementTypeDTO, MeasurementTypeDO.class);
        // 保存操作
        measurementTypeDAO.insert(measurementTypeDO);
        // 将id设置给DTO对象
        measurementTypeDTO.setId(measurementTypeDO.getId());

        return measurementTypeDTO;
    }

    @Override
    public void update(MeasurementTypeDTO measurementTypeDTO) throws ServiceException {
        // 将DTO对象的属性复制给DO对象
        MeasurementTypeDO measurementTypeDO = BeanUtils.copyToObject(measurementTypeDTO, MeasurementTypeDO.class);
        // 修改操作
        measurementTypeDAO.updateById(measurementTypeDO);
    }

    @Override
    public MeasurementTypeDTO getById(Long id) {
        // 通过主键id查询DO对象
        MeasurementTypeDO measurementTypeDO = measurementTypeDAO.selectById(id);

        return BeanUtils.copyToObject(measurementTypeDO, MeasurementTypeDTO.class);
    }

    @Override
    public PageData<MeasurementTypeVO> queryByPage(MeasurementTypePageQueryParamVO measurementTypePageQueryParamVO) throws ServiceException {
        //检验参数处理
        if(measurementTypePageQueryParamVO == null){
            measurementTypePageQueryParamVO = new MeasurementTypePageQueryParamVO();
            measurementTypePageQueryParamVO.setPageNo(GenericConstants.DEFAULT_PAGE_NO);
            measurementTypePageQueryParamVO.setPageSize(GenericConstants.DEFAULT_PAGE_SIZE);
        }
        //分页查询计量单位分类信息
        MeasurementTypePageQueryDTO measurementTypePageQueryDTO = BeanUtils.copyToObject(measurementTypePageQueryParamVO, MeasurementTypePageQueryDTO.class);
        PageData<MeasurementTypeDTO> pageDataForDTO = this.queryPage(measurementTypePageQueryDTO);
        if(pageDataForDTO == null || CollUtil.isEmpty(pageDataForDTO.getData())){
            return new PageData<>();
        }

        Collection<MeasurementTypeDTO> measurementTypeDTOS = pageDataForDTO.getData();
        ArrayList<MeasurementTypeVO> measurementTypeVOList = new ArrayList<>(measurementTypeDTOS.size());
        measurementTypeDTOS.forEach(
                measurementTypeDTO ->{
                    MeasurementTypeVO measurementTypeVO = BeanUtils.copyToObject(measurementTypeDTO, MeasurementTypeVO.class);
                    measurementTypeVOList.add(measurementTypeVO);
                }
        );
        PageData<MeasurementTypeVO> pageDataForVO = pageDataForDTO.transformExcludeData(MeasurementTypeVO.class);
        pageDataForVO.setData(measurementTypeVOList);
        return pageDataForVO;
    }
    @Override
    public PageData<MeasurementTypeDTO> queryPage(MeasurementTypePageQueryDTO measurementTypePageQueryParamVO) {
        // 封装查询条件QueryWrapper对象
        QueryWrapper<MeasurementTypeDO> queryWrapper = QueryWrapperUtils.getQueryWrapper(measurementTypePageQueryParamVO);
        queryWrapper.orderByDesc("id");
        // 分页查询数据字典信息
        Page<MeasurementTypeDO> page = Page.of(measurementTypePageQueryParamVO.getPageNo(), measurementTypePageQueryParamVO.getPageSize());
        PageData<MeasurementTypeDO> pageDataForDO = PageUtils.getPageData(measurementTypeDAO.selectPage(page, queryWrapper), measurementTypePageQueryParamVO);

        return pageDataForDO.transformData(MeasurementTypeDTO.class);
    }

    @Override
    public List<MeasurementTypeDTO> queryMeasurementTypeByName(RepeatMeasurementTypeDTO repeatMeasurementTypeDTO) {
        //封装查询条件QueryWrapper对象
        QueryWrapper<MeasurementTypeDO> wrapper = new QueryWrapper<>();
        //设置查询条件
        wrapper.eq("name", repeatMeasurementTypeDTO.getMeasurementTypeDTO().getName());
        wrapper.ne("status",9);
        //如果是更新 则去重
        if(repeatMeasurementTypeDTO.getIsUpdate()){
            wrapper.ne("id", repeatMeasurementTypeDTO.getMeasurementTypeDTO().getId());
        }
        List<MeasurementTypeDO> measurementTypeDOS = measurementTypeDAO.selectList(wrapper);
        if(measurementTypeDOS != null && !measurementTypeDOS.isEmpty()){
            return BeanUtils.copyToList(measurementTypeDOS, MeasurementTypeDTO.class);
        }else {
            return null;
        }
    }

    @Override
    public List<MeasurementTypeDTO> queryMeasurementTypeByCode(RepeatMeasurementTypeDTO repeatMeasurementTypeDTO) {
        //封装查询条件QueryWrapper对象
        QueryWrapper<MeasurementTypeDO> wrapper = new QueryWrapper<>();
        //设置查询条件
        wrapper.eq("code", repeatMeasurementTypeDTO.getMeasurementTypeDTO().getCode());
        //如果是更新 则去重
        if(repeatMeasurementTypeDTO.getIsUpdate()){
            wrapper.ne("id", repeatMeasurementTypeDTO.getMeasurementTypeDTO().getId());
        }
        List<MeasurementTypeDO> measurementTypeDOS = measurementTypeDAO.selectList(wrapper);
        if(measurementTypeDOS != null && !measurementTypeDOS.isEmpty()){
            return BeanUtils.copyToList(measurementTypeDOS, MeasurementTypeDTO.class);
        }else {
            return null;
        }
    }

    @Override
    public List<MeasurementTypeVO> queryAll() {
        //查询所有的计量单位分类结果
        QueryWrapper<MeasurementTypeDO> wrapper = new QueryWrapper<>();
        wrapper.ne("status",GenericStatusEnum.DELETED.getValue());
        List<MeasurementTypeDO> measurementTypeDOS = measurementTypeDAO.selectList(wrapper);
        //如果存在则转化为DTO对象返回
        if(measurementTypeDOS != null && !measurementTypeDOS.isEmpty())
        {
            return BeanUtils.copyToList(measurementTypeDOS, MeasurementTypeVO.class);
        }else {
            return null;
        }
    }

    /**
     * 根据名称获取计量单位分类信息
     *
     * @param measurementTypeNameList 计量单位分类名称列表
     * @return 计量单位分类信息Map key: 计量单位分类名称 value: 计量单位分类信息
     */
    @Override
    public Map<String, MeasurementTypeDTO> mapMeasurementTypeByName(List<String> measurementTypeNameList) {
        List<MeasurementTypeDO> result = measurementTypeDAO.selectList(Wrappers.<MeasurementTypeDO>lambdaQuery()
                .in(MeasurementTypeDO::getName, measurementTypeNameList)
                .eq(MeasurementTypeDO::getStatus, GenericStatusEnum.NORMAL.getValue()));
        List<MeasurementTypeDTO> measurementTypeDTOS = BeanUtils.copyToList(result, MeasurementTypeDTO.class);
        return measurementTypeDTOS.stream().collect(Collectors.toMap(MeasurementTypeDTO::getName, item -> item));
    }

    @Override
    public MeasurementTypeVO saveMeasurementType(MeasurementTypeVO measurementTypeVO) throws ServiceException {
        //获取当前用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        //封装DTO对象
        MeasurementTypeDTO measurementTypeDTO = BeanUtils.copyToObject(measurementTypeVO, MeasurementTypeDTO.class);
        measurementTypeDTO.setStatus(GenericStatusEnum.NORMAL.getValue());
        CurrentUserUtils.setCreateDefaultField(measurementTypeDTO, currentUserDTO);
        //新建查重对象
        RepeatMeasurementTypeDTO repeatMeasurementTypeDTO = new RepeatMeasurementTypeDTO();
        repeatMeasurementTypeDTO.setMeasurementTypeDTO(measurementTypeDTO);
        repeatMeasurementTypeDTO.setIsUpdate(false);
        //如果名称重复 抛出异常
        List<MeasurementTypeDTO> measurementTypeDTOSName = this.queryMeasurementTypeByName(repeatMeasurementTypeDTO);
        if(measurementTypeDTOSName != null && !measurementTypeDTOSName.isEmpty()){
            throw new ServiceException(MeasurementTypeErrorCodeEnum.NAME_REPEAT.getErrorCode(), MeasurementTypeErrorCodeEnum.NAME_REPEAT.getErrorMessage());
        }
        //如果编号重复 抛出异常
        List<MeasurementTypeDTO> measurementTypeDTOSCode = this.queryMeasurementTypeByCode(repeatMeasurementTypeDTO);
        if(measurementTypeDTOSCode != null && !measurementTypeDTOSCode.isEmpty()){
            throw new ServiceException(MeasurementTypeErrorCodeEnum.CODE_REPEAT.getErrorCode(), MeasurementTypeErrorCodeEnum.CODE_REPEAT.getErrorMessage());
        }
        //保存计量单位分类
        MeasurementTypeDTO resultDTO = this.save(measurementTypeDTO);
        //将计量单位分类DTO对象转化为VO对象，并返回
        return  BeanUtils.copyToObject(resultDTO, MeasurementTypeVO.class);
    }

    @Override
    public MeasurementTypeVO detailMeasurementType(Long measurementTypeId) throws ServiceException {
        //通过计量单位分类id获取计量单位分类DTO对象
        MeasurementTypeDTO measurementTypeDTO = this.getById(measurementTypeId);
        if(measurementTypeDTO == null){
            return null;
        }else {
            //封装计量单位分类VO对象，并返回
            return BeanUtils.copyToObject(measurementTypeDTO, MeasurementTypeVO.class);
        }
    }

    @Override
    public void updateMeasurementType(MeasurementTypeVO measurementTypeVO) throws ServiceException {
        Long measurementTypeVOId = measurementTypeVO.getId();
        if (measurementTypeVOId == null){
            throw new ServiceException(MeasurementTypeErrorCodeEnum.PARAM_MEASUREMENTTYPE_ID_IS_NULL.getErrorCode(), MeasurementTypeErrorCodeEnum.PARAM_MEASUREMENTTYPE_ID_IS_NULL.getErrorMessage());
        }
        //通过计量单位分类id获取计量单位分类DTO对象
        MeasurementTypeDTO measurementTypeDTO = this.getById(measurementTypeVOId);
        if(measurementTypeDTO == null){
            throw new ServiceException(MeasurementTypeErrorCodeEnum.PARAM_OBJECT_IS_NULL.getErrorCode(), MeasurementTypeErrorCodeEnum.PARAM_OBJECT_IS_NULL.getErrorMessage());
        }
        //获取当前登录用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        //封装待修改的计量单位分类DTO对象
        BeanUtils.copyObject(measurementTypeVO, measurementTypeDTO);
        CurrentUserUtils.setUpdateDefaultField(measurementTypeDTO, currentUserDTO);
        //新建查重对象
        RepeatMeasurementTypeDTO repeatMeasurementTypeDTO = new RepeatMeasurementTypeDTO();
        repeatMeasurementTypeDTO.setMeasurementTypeDTO(measurementTypeDTO);
        repeatMeasurementTypeDTO.setIsUpdate(true);
        //如果名称重复 抛出异常
        List<MeasurementTypeDTO> measurementTypeDTOSName = this.queryMeasurementTypeByName(repeatMeasurementTypeDTO);
        if(measurementTypeDTOSName != null && !measurementTypeDTOSName.isEmpty()){
            throw new ServiceException(MeasurementTypeErrorCodeEnum.NAME_REPEAT.getErrorCode(), MeasurementTypeErrorCodeEnum.NAME_REPEAT.getErrorMessage());
        }
        //如果编号重复 抛出异常
        List<MeasurementTypeDTO> measurementTypeDTOSCode = this.queryMeasurementTypeByCode(repeatMeasurementTypeDTO);
        if(measurementTypeDTOSCode != null && !measurementTypeDTOSCode.isEmpty()){
            throw new ServiceException(MeasurementTypeErrorCodeEnum.CODE_REPEAT.getErrorCode(), MeasurementTypeErrorCodeEnum.CODE_REPEAT.getErrorMessage());
        }
        //修改操作
        this.update(measurementTypeDTO);
    }

    @Override
    public void deleteMeasurementType(Long measurementTypeId) throws ServiceException {
        //通过计量单位分类id获取计量单位分类DTO对象
        MeasurementTypeDTO measurementTypeDTO = this.getById(measurementTypeId);
        if(measurementTypeDTO == null){
            throw new ServiceException(MeasurementTypeErrorCodeEnum.PARAM_NOT_FIND.getErrorCode(), MeasurementTypeErrorCodeEnum.PARAM_NOT_FIND.getErrorMessage());
        }
        //获取当前登录用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        //封装待修改的计量单位分类DTO对象
        measurementTypeDTO.setStatus(GenericStatusEnum.DELETED.getValue());
        CurrentUserUtils.setUpdateDefaultField(measurementTypeDTO, currentUserDTO);
        //修改操作
        this.update(measurementTypeDTO);
    }

    @Override
    public void disableMeasurementType(Long measurementTypeId) throws ServiceException {
        //通过计量单位分类id获取计量单位分类DTO对象
        MeasurementTypeDTO measurementTypeDTO = this.getById(measurementTypeId);
        if (measurementTypeDTO == null) {
            throw new ServiceException(MeasurementTypeErrorCodeEnum.PARAM_OBJECT_IS_NULL.getErrorCode(), MeasurementTypeErrorCodeEnum.PARAM_OBJECT_IS_NULL.getErrorMessage());
        }

        //获取当前登录用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        //封装待修改的计量单位分类DTO对象
        measurementTypeDTO.setStatus(GenericStatusEnum.DISABLE.getValue());
        CurrentUserUtils.setUpdateDefaultField(measurementTypeDTO, currentUserDTO);

        //修改操作
        this.update(measurementTypeDTO);
    }

    @Override
    public void enableMeasurementType(Long measurementTypeId) throws ServiceException {
        ///通过计量单位分类id获取记录力量单位分类DTO对象
        MeasurementTypeDTO measurementTypeDTO = this.getById(measurementTypeId);
        if (measurementTypeDTO == null) {
            throw new ServiceException(MeasurementTypeErrorCodeEnum.PARAM_OBJECT_IS_NULL.getErrorCode(), MeasurementTypeErrorCodeEnum.PARAM_OBJECT_IS_NULL.getErrorMessage());
        }

        //获取当前登录用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        //封装待修改的计量单位分类DTO对象
        measurementTypeDTO.setStatus(GenericStatusEnum.NORMAL.getValue());
        CurrentUserUtils.setUpdateDefaultField(measurementTypeDTO, currentUserDTO);

        //修改操作
        this.update(measurementTypeDTO);
    }
}

